﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using MyCRM.Infrastructure.Storage;

namespace MyCRM.Infrastructure.Repositories
{
    public class ReadModelRepository : IReadModelRepository
    {
        readonly IUnitOfWork _unitOfWork;

        public ReadModelRepository(IReadModelUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        public IEnumerable<T> QueryAll<T>() where T : class, new()
        {
            return _unitOfWork.Query<T>();
        }

        public IEnumerable<T> QueryBy<T>(Expression<Func<T, bool>> predicate) where T : class, new()
        {
            return _unitOfWork.Query<T>().Where(predicate);
        }

        public T FindBy<T>(Expression<Func<T, bool>> predicate) where T : class, new()
        {
            try
            {
                return _unitOfWork.Query<T>().Single(predicate);
            }
            catch
            {
                return null;
            }
        }

        public T First<T>(Expression<Func<T, bool>> predicate) where T : class, new()
        {
            try
            {
                return _unitOfWork.Query<T>().First(predicate);
            }
            catch
            {
                return null;
            }

        }

        public void Create<T>(T entity) where T : class, IEntity, new()
        {
            _unitOfWork.Store(entity);
            _unitOfWork.SaveChanges();
        }

        public void Create(object entity)
        {
            _unitOfWork.Store(entity);
        }

        public void Update<T>(T entity) where T : class, IEntity, new()
        {
            _unitOfWork.Store(entity);
            _unitOfWork.SaveChanges();
        }

        public void Update(object valueObject)
        {
            _unitOfWork.Store(valueObject);
        }

        public void Delete<T>(T entity) where T : class, IEntity, new()
        {
            _unitOfWork.Delete(entity);
        }

        public void Delete(object entity)
        {
            _unitOfWork.Delete(entity);
        }
    }
}
